﻿using System;
using System.Collections.Generic;
using System.Text;
using B4ALL.JITL.Contract;
using Spring.Context;
using Spring.Context.Support;
using B4ALL.Common;
using System.Reflection;

namespace B4ALL.JITL
{
    [Serializable()]
    public class JITLObject : IJITLObject
    {

        private Boolean isLoaded = false;
        private Boolean isDummyObject = false;
        private JITLReference reference = null;
        private Boolean isNull = false;

        #region IJITLObject Members

        public bool IsDummyObject
        {
            get { return isDummyObject; }
        }

        public bool IsLoaded
        {
            get { return isLoaded; }
        }

        public bool IsNull
        {
            get { return isNull; }
        }

        public JITLReference Reference
        {
            get { return reference; }
            set
            {
                reference = value;
                isDummyObject = true;
            }
        }

        public void Load(Object obj)
        {
            JITLContext ctx = Context.GetContext<JITLContext>();

            if (ctx == null || ctx.DelayLoad)
            {
                IJITLObject jitlObject = (IJITLObject)obj;

                if (jitlObject.IsDummyObject && !jitlObject.IsLoaded)
                {
                    IApplicationContext l_ctx = ContextRegistry.GetContext();
                    IJITLService JITLService = (IJITLService)l_ctx.GetObject("JITLService");

                    JITLService.LoadByRef(obj);
                }
            }
        }

        public void Copy(ref Object objSource, ref Object objTarget)
        {

            if (objSource != null)
            {
                PropertyInfo[] properties = objSource.GetType().GetProperties();
                foreach (PropertyInfo propInfo in properties)
                {
                    if (propInfo.CanWrite)
                    {
                        propInfo.SetValue(objTarget,
                            propInfo.GetValue(objSource, null),
                            null
                        );
                    }
                }
            }
            else
                isNull = true;

            isLoaded = true;
        }

        public Boolean Equals(Object otherObj)
        {
            return false;
        }

        #endregion

        #region Boolean operators overload
        public static Boolean Equality(Object obj1src, Object obj2src)
        {
            IJITLObject obj1 = (IJITLObject)obj1src;
            IJITLObject obj2 = (IJITLObject)obj2src;

            if (obj1 != null && !obj1.IsLoaded && obj1.IsDummyObject)
                obj1.Load(obj1);

            if (obj2 != null && !obj2.IsLoaded && obj2.IsDummyObject)
                obj2.Load(obj2);

            if (obj1 == null && obj2 == null)
                return true;
            else if ((obj1 == null || obj1.IsNull) && (obj2 == null || obj2.IsNull))
                return true;
            else if ((obj1 == null || obj1.IsNull) && (obj2 != null && !obj2.IsNull))
                return false;
            else if ((obj2 == null || obj2.IsNull) && (obj1 != null && !obj1.IsNull))
                return false;
            else return obj1.Equals(obj2);
        }
        #endregion Boolean operators overload

    }
}